//
//  SCSHuanXinManager.m
//  YCSuperSDK_Plugin_VipCustomer
//
//  Created by MacPro on 2021/4/30.
//

#import "SCSHuanXinManager.h"
#import "HelpDeskLite/HDClient.h"
#import "ArgumentStore.h"
#import "ImManager.h"

@interface SCSHuanXinManager()
@property(nonatomic, strong)NSMutableDictionary *evalMessageMap;
@end

@implementation SCSHuanXinManager

static SCSHuanXinManager *_instance;
+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
        [_instance initialize];
    });
    return _instance;
}


- (void)initialize {
    [[ImManager getInstance] addImMessageObserver:self selector:@selector(receiveImMessage:)];
    _evalMessageMap = [[NSMutableDictionary alloc] init];
}

#pragma mark -
// 获取未读消息
- (NSNumber *)getUnreadMsgNum {
    return [[ImManager getInstance] getUnreadMsgNum];
}

// 标记消息已读
- (void)markAllMsgAsRead {
    dispatch_async(dispatch_get_main_queue(), ^{
      HDConversation *conversation = [[HDClient sharedClient].chatManager getConversation:[ArgumentStore.current conversationId]];
      [conversation markAllMessagesAsRead:nil];
    });
}

// 拉取历史消息
- (void)pullMessage:(NSString *)messageId
              count:(int)loadCount
           response:(void(^)(NSDictionary *obj))response {
    NSLog(@"pullMessage, messageId=%@", messageId);
    dispatch_async(dispatch_get_main_queue(), ^{
        HDConversation *conversation = [[HDClient sharedClient].chatManager getConversation:[ArgumentStore.current conversationId]];
        // 指定会话消息未读数清零
        [conversation markAllMessagesAsRead:nil];
        // 获取历史记录
        NSString *inputMessageId;
        if (messageId == nil || messageId.length == 0) {
            inputMessageId = nil;
        } else {
            inputMessageId = messageId;
        }
        [conversation loadMessagesStartFromId:inputMessageId count:loadCount searchDirection:HDMessageSearchDirectionUp completion:^(NSArray *aMessages, HDError *aError) {
            if (aError) {
                NSLog(@"pullMessage error! messageId=%@, error=%@", messageId, aError);
            } else {
                // 异步加载消息
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    NSMutableArray *historyMsg = [[NSMutableArray alloc] init];
                    for (HDMessage *msg in aMessages) {
                        NSDictionary *map = nil;
                        if ([HDMessageHelper isEvaluationMessage:msg]) {
                            // 处理评价消息
                            map = [self formatEvalMessage:msg];
                        } else {
                            // 处理其他消息
                            switch (msg.body.type) {
                                case EMMessageBodyTypeText:
                                    map = [self formatTextMessage:msg];
                                    break;
                                case EMMessageBodyTypeImage:
                                    map = [self formatImageMessage:msg];
                                    break;
                                case EMMessageBodyTypeVoice:
                                    break;
                                    
                                default:
                                    break;
                            }
                        }
                        if (map) {
                            [historyMsg addObject:map];
                        }
                    }
                    if (response) {
                        NSDictionary *dict = @{@"code": @"0",
                                               @"list": historyMsg};
                        response(dict);
                    }
                });
            }
        }];
    });
}

// 发送消息
- (void)sendMessageWithType:(NSString *)type
                        msg:(NSString *)msg
                visitorInfo:(NSDictionary *)visitorInfo
                     result:(void(^)(NSDictionary *obj))result {
    if ([type isEqual:@"text"]) {
        [self sendText:msg visitorInfo:visitorInfo result:result];
    } else if ([type isEqual:@"image"]) {
        [self sendImage:msg visitorInfo:visitorInfo result:result];
    }
}

// 发送文字消息
- (void)sendText:(NSString *)txt
     visitorInfo:(NSDictionary *)visitorInfo
          result:(void(^)(NSDictionary *obj))result {
  NSLog(@"sendTextWithVisitorInfo, txt=%@", txt);
  //创建文本消息
  HDMessage *message = [HDMessage createTxtSendMessageWithContent:txt to:[ArgumentStore.current conversationId]];
  [self sendMsg:message ext:visitorInfo result:result];
}

// 发送图片消息给环信
- (void)sendImage:(NSString *)imagePath
      visitorInfo:(NSDictionary *)visitorInfo
           result:(void(^)(NSDictionary *obj))result {
    NSLog(@"sendImageMessageWithVisitorInfo, imagePath=%@", imagePath);
    if (!imagePath || imagePath.length <= 0) {
        if (result) {
            NSDictionary *dict = @{
                @"sendMessage": @"",
                @"code": @"-1",
                @"error": @"图片为空，无法发送"
            };
            result(dict);
        }
        return;
    }
    NSString *base64String = @"";
    NSArray *stringArray = [imagePath componentsSeparatedByString:@"base64,"];
    if (stringArray.count > 1) {
        base64String = stringArray.lastObject;
    }
    NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64String options:NSDataBase64DecodingIgnoreUnknownCharacters];
//    NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
    
    UIImage *image = [UIImage imageWithData:imageData];
    if (image == nil) {
        if (result) {
            NSDictionary *dict = @{
                @"sendMessage": @"",
                @"code": @"-1",
                @"error": @"图片为空，无法发送"
            };
            result(dict);
        }
        return;
    }
    
    //创建图片消息
    EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:imageData displayName:@""];
//    body.compressionRatio = 1.0;// 不压缩
    HDMessage *message = [[HDMessage alloc] initWithConversationID:[ArgumentStore.current conversationId] from:[HDClient sharedClient].currentUsername to:[ArgumentStore.current conversationId] body:body];
    [self sendMsg:message ext:visitorInfo result:result];
}

// 发送评价结果给环信
- (void)sendEvalMsg:(NSDictionary *)data result:(void(^)(NSDictionary *obj))result {
    NSLog(@"sendEvalMsg, data=%@", data);
    int score = [[data objectForKey:@"degree"] intValue];
    NSString *text = [data objectForKey:@"content"];
    NSString *messageId = [data objectForKey:@"message_id"]?:@"";
    NSString *inviteId = [data objectForKey:@"invite_id"];
    NSString *sessionId = [data objectForKey:@"session_id"];
    NSArray * tags = [data objectForKey:@"tag"];// 选中的tagId数组
    NSLog(@"评价分数为： %d; 评价内容： %@", score, text);
    
    // 查询缓存的"待评价"消息
    NSDictionary *cacheMessage = [_evalMessageMap objectForKey:messageId];
    
    ControlType *type = [[ControlType alloc] initWithValue:@"enquiry"];
    ControlArguments *arguments = [ControlArguments new];
    arguments.sessionId = [cacheMessage objectForKey:@"sessionId"];
    arguments.inviteId = [cacheMessage objectForKey:@"inviteId"];;
    arguments.detail = text;
    arguments.summary = [NSString stringWithFormat:@"%d", score];
    HDControlMessage *hCtrl = [HDControlMessage new];
    hCtrl.type = type;
    hCtrl.arguments = arguments;
    if (![sessionId isEqualToString:arguments.sessionId] || ![inviteId isEqualToString:arguments.inviteId]) {
        if (result) {
            NSDictionary *dict = @{
                @"code": @"-1",
                @"sendMessage": messageId,
                @"degree": @(score),
                @"content": text ?: @"",
                @"error": @"消息数据不一致，无法评价"
            };
            result(dict);
        }
        return;
    }
    
    // 构造评价消息
    HDMessage *message = [HDMessage createTxtSendMessageWithContent:@"" to:[ArgumentStore.current conversationId]];
    [message addCompositeContent:hCtrl];
    // 获取选中的tag
    NSDictionary *cacheDegreeList = [cacheMessage objectForKey:@"degreeList"];
    NSDictionary *degreeInfo = [cacheDegreeList objectForKey:[NSString stringWithFormat:@"%d", score]];
    NSArray *cacheTagList;
    if (degreeInfo) {
        cacheTagList = [degreeInfo objectForKey:@"tags"];
    }
    if (!cacheTagList) {
        //    reject(@"-1", @"无法获取标签数据，无法评价", nil);
        if (result) {
            NSDictionary *dict = @{
                @"code": @"-2",
                @"sendMessage": messageId,
                @"degree": @(score),
                @"content": text ?: @"",
                @"error": @"无法获取标签数据，无法评价"
            };
            result(dict);
        }
        return;
    }
    NSMutableArray *selectedTags = [[NSMutableArray alloc] init];
    for (NSDictionary *cacheTag in cacheTagList) {
        NSString *tagId = [cacheTag objectForKey: @"tagId"];
        if ([tags containsObject:tagId]) {
            [selectedTags addObject:@{@"id":tagId, @"name":[cacheTag objectForKey:@"tagName"]}];
        }
    }
    // 将评价标签加到消息的ext中
    NSMutableDictionary *ext = [message.ext mutableCopy];
    NSMutableDictionary *ctrlArgsCopy = [[ext objectForKey:@"weichat"] objectForKey:@"ctrlArgs"];
    NSArray *tagsArray = [NSArray arrayWithArray:selectedTags];
    [ctrlArgsCopy setObject:tagsArray forKey:@"appraiseTags"];
    message.ext = [ext copy];
    
    //必须切换到ui线程发送消息，否则无法收到调用返回
    dispatch_async(dispatch_get_main_queue(), ^{
        [[HDClient sharedClient].chatManager sendMessage:message
                                                progress:nil
                                              completion:^(HDMessage *aMessage, HDError *aError)
         {
            if (!aError) {
                // 发送成功，刷新界面
                NSLog(@"评价成功，刷新界面, message=%@", messageId);
                
                // 发送评价成功则把该条聊天记录从会话中删除
                HDConversation *conversation = [[HDClient sharedClient].chatManager getConversation:[ArgumentStore.current conversationId]];
                [conversation removeMessageWithMessageId:messageId error:nil];
                if (result) {
                    NSDictionary *dict = @{
                        @"code": @"0",
                        @"sendMessage": messageId,
                        @"status": @"success",
                        @"degree": @(score),
                        @"content": text ?: @"",
                    };
                    result(dict);
                }
            } else {
                // 发送失败
                NSLog(@"评价失败，刷新界面, message=%@,error=%@", messageId, aError);
                NSString * code = [NSString stringWithFormat:@"%d",aError.code]?:@"-999";
                if (result) {
                    NSDictionary *dict = @{
                        @"code": code,
                        @"sendMessage": messageId,
                        @"degree": @(score),
                        @"content": text ?: @"",
                        @"error": aError.errorDescription?:@"发送失败"
                    };
                    result(dict);
                }
            }
        }];
    });
}

#pragma mark - ImManager callback im消息回调

// 收到消息
- (void)receiveImMessage:(NSNotification *) notification {
  NSArray *aMessages = [notification object];
  if (aMessages == nil) {
    return;
  }
  for (HDMessage *message in aMessages) {
    if ([HDMessageHelper isEvaluationMessage:message]) {
      NSLog(@"receiveEvalMessage, msg=%@", message);
      NSDictionary *eventBody = [self formatEvalMessage:message];
      if (eventBody != nil && _receiveMessageHandler) {
          _receiveMessageHandler(eventBody);
      }
      break;
    } else {
      switch (message.body.type) {
        case EMMessageBodyTypeText: {
          NSLog(@"receiveTextMessage, msg=%@", message);
          NSDictionary *eventBody = [self formatTextMessage:message];
          if (eventBody != nil && _receiveMessageHandler) {
              _receiveMessageHandler(eventBody);
          }
          break;
        }
        case EMMessageBodyTypeImage: {
          NSLog(@"receiveImageMessage, msg=%@", message);
          // 异步处理图片
          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSDictionary *eventBody = [self formatImageMessage:message];
            if (eventBody != nil && self.receiveMessageHandler) {
                self.receiveMessageHandler(eventBody);
            }
          });
          break;
        }
        default:
          break;
      }
    }
  }
}

#pragma mark - private method 私有方法

// 发送消息，附带额外访客信息
- (void)sendMsg:(HDMessage *)message
            ext:(NSDictionary *)ext
         result:(void(^)(NSDictionary *obj))result {
  NSString *group = [ext valueForKey:@"group"];
  NSString *nickName = [ext valueForKey:@"nick_name"];
  NSString *name = [ext valueForKey:@"name"];
  NSString *qq = [ext valueForKey:@"qq"];
  NSString *phone = [ext valueForKey:@"phone"];
  NSString *companyName = [ext valueForKey:@"company_name"];
  NSString *description = [ext valueForKey:@"desc"];
  NSString *email = [ext valueForKey:@"email"];
  
  // 添加额外访客信息
  HDVisitorInfo *visitor = [[HDVisitorInfo alloc] init];
  visitor.nickName = nickName;
  visitor.name = name;
  visitor.qq = qq;
  visitor.phone = phone;
  visitor.companyName = companyName;
  visitor.email = email;
  visitor.desc = description;
  [message addContent:visitor];
  
  // 添加技能组
  if (group != nil && group.length > 0) {
    [message addContent: [[HDQueueIdentityInfo alloc] initWithValue:group]];
  }
  //必须切换到ui线程发送消息，否则无法收到调用返回
  dispatch_async(dispatch_get_main_queue(), ^{
    [[HDClient sharedClient].chatManager sendMessage:message
                                            progress:nil
                                          completion:^(HDMessage *message, HDError *error)
     {
       if (!error) {
         // 发送成功，刷新界面
         NSLog(@"消息发送成功，刷新界面, message=%@", message);
           if (result) {
               NSDictionary *dict = @{
                   @"sendMessage": message.messageId,
                   @"code": @"0",
               };
               result(dict);
           }
       } else {
         // 发送失败
         NSLog(@"消息发送失败，刷新界面, message=%@,error=%@", message, error);
         NSString * code = [NSString stringWithFormat:@"%d",error.code];
           if (result) {
               NSDictionary *dict = @{
                   @"sendMessage": message.messageId,
                   @"code": code,
                   @"error": error.errorDescription
               };
               result(dict);
           }
//         reject(code, error.errorDescription, nil);
       }
     }];
  });
}

// 获取昵称
// 文档 http://docs.easemob.com/cs/300visitoraccess/extended-message-format#%E6%98%BE%E7%A4%BA%E5%AE%A2%E6%9C%8D%E5%A4%B4%E5%83%8F%E5%92%8C%E6%98%B5%E7%A7%B0
- (NSString *)getNicknameFromMessage:(HDMessage *)message {
  NSString *avatar = @"";
  NSDictionary *weichat = [message.ext objectForKey:@"weichat"];
  if (weichat) {
    NSDictionary *agent = [weichat objectForKey:@"agent"];
    if (agent) {
      NSString *avatarStr = [agent objectForKey:@"userNickname"];
      if (avatarStr) {
        avatar = avatarStr;
      }
    }
  }
  return avatar;
}

// 获取头像
// 文档 http://docs.easemob.com/cs/300visitoraccess/extended-message-format#%E6%98%BE%E7%A4%BA%E5%AE%A2%E6%9C%8D%E5%A4%B4%E5%83%8F%E5%92%8C%E6%98%B5%E7%A7%B0
- (NSString *)getAvatarFromMessage:(HDMessage *)message {
  NSString *avatar = @"";
  NSDictionary *weichat = [message.ext objectForKey:@"weichat"];
  if (weichat) {
    NSDictionary *agent = [weichat objectForKey:@"agent"];
    if (agent) {
      NSString *avatarStr = [agent objectForKey:@"avatar"];
      if (avatarStr) {
        avatar = avatarStr;
      }
    }
  }
  return avatar;
}

// 将文字消息转成map
- (NSDictionary *)formatTextMessage:(HDMessage *)message {
  EMTextMessageBody *textBody = (EMTextMessageBody *)message.body;
  NSString *text = textBody.text;
  //如果是当前会话的消息，刷新聊天页面
  if (text != nil && text.length > 0) {
    return @{@"messageType":[NSNumber numberWithInt:message.direction],
             @"type":@"receiveText",
             @"content":text,
             @"messageId":message.messageId,
             @"avatar":[self getAvatarFromMessage:message],
             @"nickname":[self getNicknameFromMessage:message],
             @"timestamp":[NSNumber numberWithLongLong:[[NSDate date] timeIntervalSince1970]*1000]};
  } else {
    return nil;
  }
}

// 将图片消息转成map
- (NSDictionary *)	formatImageMessage:(HDMessage *)message {
    EMImageMessageBody *imgMessageBody = (EMImageMessageBody *)message.body;
    NSString *filePath = @"";
    int width = 0;
    int height = 0;
    if (message.direction == HDMessageDirectionReceive) {
        // 接收的图片，直接从远程获取
        filePath = imgMessageBody.remotePath;
        width = imgMessageBody.size.width;
        height = imgMessageBody.size.height;
        
    } else {
        // 发送的图片，从本地获取
        filePath = imgMessageBody.localPath;
        UIImage *img = [UIImage imageWithContentsOfFile:filePath];
        if (img == nil) {
            NSLog(@"图片不存在，filePath=%@", filePath);
            return nil;
        }
        width = img.size.width;
        height = img.size.height;
        //本地图片转格式
        filePath=[self.class ImageFormateToJPEG:filePath];
        // 转base64
        NSData *imageData = UIImageJPEGRepresentation(img, 1.0);
        filePath = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
        filePath = [NSString stringWithFormat:@"data:image/jpg;base64,%@", filePath];
    }
    NSLog(@"图片路径=%@", filePath);
    return @{@"messageType":[NSNumber numberWithInt:message.direction],
             @"type":@"receiveImage",
             @"content":filePath,
             @"messageId":message.messageId,
             @"imageWidth":[NSNumber numberWithInt:width],
             @"imageHeight":[NSNumber numberWithInt:height],
             @"avatar":[self getAvatarFromMessage:message],
             @"nickname":[self getNicknameFromMessage:message],
             @"timestamp":[[NSNumber numberWithLongLong:message.messageTime] stringValue]};
}

+(NSString *) ImageFormateToJPEG:(NSString *)imgUrl {
  //依据内容拆分数组
  NSArray *array = [imgUrl componentsSeparatedByString:@"/"];
  NSString *fileName=@"";
  if(array!=nil && [array count]>0) {
    fileName=(NSString *)[array lastObject];
  } else {
    fileName=[NSString stringWithFormat:@"%d",arc4random()];
  }
  fileName=[fileName stringByAppendingString:@".jpg"];
  UIImage *img=[UIImage imageWithData:[NSData dataWithContentsOfFile:imgUrl]];
  UIImageJPEGRepresentation(img, 1.0);
  NSString *pathSandox = NSHomeDirectory();
  NSString *imagePath = [pathSandox stringByAppendingString:[@"/Documents/tmp" stringByAppendingString:fileName]];
  //把图片直接保存到指定的路径（同时应该把图片的路径imagePath存起来，下次就可以直接用来取）
  [UIImageJPEGRepresentation(img,1) writeToFile:imagePath atomically:YES];
  return imagePath;
}

// 将评价消息转成map
- (NSDictionary *)formatEvalMessage:(HDMessage *)message {
  // 解析评价信息
  NSDictionary *ctrlArgs = nil;
  NSDictionary *weichat = [message.ext objectForKey:@"weichat"];
  if (weichat) {
    ctrlArgs = [weichat objectForKey:@"ctrlArgs"];
  }
  if (!ctrlArgs) {
    // 没有评价信息
    NSLog(@"没有评价信息");
    return nil;
  }
  NSLog(@"ctrlArgs--%@", ctrlArgs);
  EMTextMessageBody *textBody = (EMTextMessageBody *)message.body;
  NSString *receiveMessage =textBody.text;
  NSString *sessionId = [ctrlArgs objectForKey:@"serviceSessionId"];
  NSString *inviteId = [NSString stringWithFormat:@"%@", [ctrlArgs objectForKey:@"inviteId"]];
  NSArray *degreeList = [ctrlArgs objectForKey:@"evaluationDegree"];
  NSMutableDictionary *degreeMap = [[NSMutableDictionary alloc] init];
  for (NSDictionary *degree in degreeList) {
    NSArray *tagInfoList = [degree objectForKey:@"appraiseTags"];
    NSMutableDictionary *degreeInfo = [[NSMutableDictionary alloc] init];
    NSMutableArray *tags = [[NSMutableArray alloc] init];
    for (NSDictionary* tagInfo in tagInfoList) {
      [tags addObject:@{@"tagId":[tagInfo objectForKey:@"id"], @"tagName":[tagInfo objectForKey:@"name"]}];
    }
    [degreeInfo setObject:tags forKey:@"tags"];
    [degreeInfo setObject:[degree objectForKey:@"name"] forKey:@"name"];
    [degreeInfo setObject:[degree objectForKey:@"level"] forKey:@"level"];
    
    NSString *score = [NSString stringWithFormat:@"%@", [degree objectForKey:@"score"]];;
    [degreeMap setObject:degreeInfo forKey:score];
  }
  NSDictionary *result = @{@"messageType":[NSNumber numberWithInt:message.direction],
                           @"type":@"receiveEval",
                           @"content":receiveMessage,
                           @"messageId":message.messageId,
                           @"inviteId":inviteId,
                           @"sessionId":sessionId,
                           @"degreeList":degreeMap,
                           @"avatar":[self getAvatarFromMessage:message],
                           @"nickname":[self getNicknameFromMessage:message],
                           @"timestamp":[[NSNumber numberWithLongLong:message.messageTime] stringValue]};
  // 缓存到本地
  [_evalMessageMap setObject:result forKey:message.messageId];
  return result;
}


@end
